import { dom } from '@knno/dom';
import IconUnchecked from '@material-design-icons/svg/filled/radio_button_unchecked.svg';
import IconChecked from '@material-design-icons/svg/filled/radio_button_checked.svg';
import { checkStyle } from '../checkbox/check.css';
import { Checkable } from '../checkbox/checkable';
import { DATA } from '../symbol';
const RADIO_DATA = Symbol();

export class Radio extends Checkable {
	protected [RADIO_DATA] = {
		uncheckable: false,
	};
	updateFacade(): void {
		this.root.remove(this.query(':scope>svg'));
		this.root.insert(
			dom.html(this.checked() ? this[DATA]?.checked ?? IconChecked : this[DATA]?.unchecked ?? IconUnchecked)
		);
	}
	constructor() {
		super(
			dom.button(checkStyle).attr('type', 'radio').attr({
				checked: 'false',
			})
		);
		this.root.append(dom.html(this[DATA]?.unchecked ?? IconUnchecked));
		this.on('click', () => {
			if (this.disabled()) return;
			const oldValue = this.checked();
			if (this[RADIO_DATA].uncheckable) {
				this.checked(!oldValue);
			} else {
				this.checked(true);
			}
			if (oldValue != this.checked()) {
				this.emit(new Event('change', { bubbles: true }));
			}
		});
		this.on('update', (evt) => {
			this.checked(evt.detail.checked);
		});
	}

	uncheckable(): boolean;
	uncheckable(value: boolean): this;
	uncheckable(value?: boolean): this | boolean {
		if (value === undefined) {
			return this[RADIO_DATA].uncheckable;
		} else {
			this[RADIO_DATA].uncheckable = value;
			return this;
		}
	}

	checked(): boolean;
	checked(value: boolean): this;
	checked(value?: boolean): this | boolean {
		const currentValue = this.attr('checked') === 'true';
		if (value === undefined) {
			return currentValue;
		} else {
			if (currentValue !== value) {
				this.attr('checked', value ? 'true' : null);
				this.updateFacade();
				if (value && this.group()) {
					dom
						.query(`button.${checkStyle}[type=radio][group="${this.group().replace(/"/, '\\"')}"]`)
						.filter((btn) => btn !== this[0])
						.forEach((item) => {
							const btn = dom.wrap(item);
							btn.emit(new CustomEvent('update', { detail: { checked: false } }));
						});
				}
			}
			return this;
		}
	}

	group(): string;
	group(name: string | null): this;
	group(name?: string | null): this | string | null {
		if (name !== undefined) {
			this.attr('group', name);
			return this;
		}
		return this.attr('group');
	}
}

export function radio(...className: string[]): Radio {
	return new Radio().addClass(...className);
}
